#include<iostream>
#include"parsing.h"
#include"moviles.h"
#include<cstring>
#include<cstdlib>
#include<string>
#include<vector>

using namespace std;


Parsing::Parsing(){

    //Inicializo el vector de mensajes desde aquí porque no cambian

    mismensajes.push_back("before_kick_off");
    mismensajes.push_back("play_on");
    mismensajes.push_back("corner_kick_l");
    mismensajes.push_back("corner_kick_r");
    mismensajes.push_back("drop_ball");
    mismensajes.push_back("offside_l");
    mismensajes.push_back("offside_r");
    mismensajes.push_back("half_time");
    mismensajes.push_back("time_over");
    mismensajes.push_back("time_up_without_a_team");
    mismensajes.push_back("time_up");
    mismensajes.push_back("time_extended");
    mismensajes.push_back("kick_off_l");
    mismensajes.push_back("kick_off_r");
    mismensajes.push_back("kick_in_l");
    mismensajes.push_back("kick_in_r");
    mismensajes.push_back("free_kick_l");
    mismensajes.push_back("free_kick_r");
    mismensajes.push_back("foul_l");
    mismensajes.push_back("foul_r");
    mismensajes.push_back("goal_kick_l");
    mismensajes.push_back("goal_kick_r");
    mismensajes.push_back("goal_l");
    mismensajes.push_back("goal_r");
    mismensajes.push_back("goalie_catch_ball_l");
    mismensajes.push_back("goalie_catch_ball_r");

}

int Parsing::seleccion(string &mensaje)
{
    if (veo(mensaje,"init"))
        return 1;
    if (veo(mensaje,"reconnect"))
        return 2;
    if (veo(mensaje,"error"))
        return 3;

    if (veo(mensaje,"see"))
        return 5;
    if (veo(mensaje,"hear"))
        if (veo(mensaje,"referee"))
            return 4;
        else
            return 6;
    if (veo(mensaje,"sense"))
        return 7;
    return 0;
}

/*El mensaje que le llega a esta función es la cadena completa que se
  recibe del servidor, la función se encarga de separarla y analizarla*/

int Parsing::getMensajeArbitro(char *message){

    char *orden, *men; //Cadenas auxiliares para guardar los "tokens"
    char str[1000];//Creo esta cadena para el caso especial que pongo abajo
    strcpy(str,message);

    orden=strtok (message," ())");

    while (orden!=NULL)
    {
       men=orden;
       orden=strtok(NULL," ())");
    }

    int pos=-1; //posición del vector
    int aux, aux2;//aux2 es el resultado de strcmp (0 si las cadenas son iguales)

    for(aux=0; aux<mismensajes.size(); aux++){

        aux2=strcmp(men, mismensajes[aux]);

        if (aux2==0){

            pos=aux;

        }

    }

    cout<<pos<<endl;
    //Añado un caso especial para los goles, por que la cadena no es la misma siempre, es goal_l_X, donde X son los goles
    string mensaje(str);
    size_t posicion=mensaje.find("goal_l");

    if(posicion!=string::npos)
    {
        cout<<endl<<"retorna 22"<<endl;
        return 22;
    }
    posicion=mensaje.find("goal_r");

    if(posicion!=string::npos)
    {
        cout<<endl<<"retorna 23"<<endl;
        return 23;
    }

    return pos;

}

/* Este es el vector de mensajes del arbitro, donde se puede ver la posición
de cada mensaje que es el valor que devuelve la función getMensajeArbitro.


    mismensajes[0]="before_kick_off";
    mismensajes[1]="play_on";
    mismensajes[2]="corner_kick_l";
    mismensajes[3]="corner_kick_r";
    mismensajes[4]="drop_ball";
    mismensajes[5]="offside_l";
    mismensajes[6]="offside_r";
    mismensajes[7]="half_time";
    mismensajes[8]="time_over";
    mismensajes[9]="time_up_without_a_team";
    mismensajes[10]="time_up";
    mismensajes[11]="time_extended";
    mismensajes[12]="kick_off_l";
    mismensajes[13]="kick_off_r";
    mismensajes[14]="kick_in_l";
    mismensajes[15]="kick_in_r";
    mismensajes[16]="free_kick_l";
    mismensajes[17]="free_kick_r";
    mismensajes[18]="foul_l";
    mismensajes[19]="foul_r";
    mismensajes[20]="goal_kick_l";
    mismensajes[21]="goal_kick_r";
    mismensajes[22]="goal_l";
    mismensajes[23]="goal_r";
    mismensajes[24]="goalie_catch_ball_l";
    mismensajes[25]="goalie_catch_ball_r";

*/

bool Parsing::veo( string& mensaje,  string objeto, Marca *coordenadas)
{

size_t posicion=mensaje.find(objeto);

if(posicion!=string::npos)
{


       coordenadas->dist=atof(mensaje.substr(mensaje.find(')', posicion)+1).c_str());
       coordenadas->ang=atof(mensaje.substr(mensaje.find(' ',(mensaje.find(')',posicion)+2))).c_str());
       return 1;
}
else
    return 0;



}
bool Parsing::veo( string& mensaje,  string objeto)
{

size_t posicion=mensaje.find(objeto);

if(posicion!=string::npos)
    return 1;
else
    return 0;
}


/*
bool Parsing::posicion (float *x, float *y, char *mensaje)
{
    int i = 7;
    list <Marca> flags;
    Marca flag;
    x=0;
    y=0;


    do			//leemos toda la cadena y cada flag la almacenamos en la lista
       {
        if (mensaje[i]=='f' && mensaje [i+1] =='l')
        flag.fill(i, mensaje)
            flags.push_front(flag);
       }
    while((i+1)>strlen(mensaje);
    if (flags.size()=0)
        return 0;
    float sumadist=0;
   list<Marca>::iterator it;
    for (it=flags.begin(); it!=flags.end();it++)
    {
    sumadist=sumadist+((*it).dist^2);	 //calculamos la suma del cuadrado de todas las distancias
        x=x+((cos((*it).ang)*(*it).dis)*((*it).dis^2));
        y=y+((sin((*it).ang)*(*it).dis)*((*it).dis^2));    //sumamos la posición absoluta multiplicada por el cuadrado de la distancia a cada flag
    }
    x=x/sumadist;		//ponderamos segun el cuadrado de la distancia. Las flag mas cercanas cuentan mas, ya que son mas precisas
    y=y/sumadist;

return 1;
}
*/

BalonParams Parsing::balon(char* mensaje)
{

    char cadena [2048];
    int i=0,n=0,k=0;
    int espacios;
    char numero[8];
    float BALL[4];
    int found;
    BalonParams Parametro;
    strcpy(cadena,mensaje);
    string str(cadena);

    found=str.find("ball");
    if(found!=-1)
    {
                for(i=found+6, n=0, k=0, espacios=0; espacios<4; i++,n++)
                {
                    numero[n]=cadena[i];
                    if(cadena[i]==32||cadena[i]==')')
                    {
                        BALL[k]=atof(numero);
                        k++;
                        n=-1;
                        espacios++;
                        bzero(numero, 8);


                    }
                }


        Parametro.Distancia=BALL[0];
        Parametro.Angulo=BALL[1];
        Parametro.Velocidad[0]=BALL[2];
        Parametro.Velocidad[1]=BALL[3];
    }


    bzero(cadena,2048);
    return Parametro;
}

JugadorParams Parsing::jugadores(char* mensaje, string miequipo)
{

    cout<<"\n\n---GETPLAYERS---\n\n";

    JugadorParams jugMasCerca;
    jugMasCerca.Distancia=9999999999;
    JugadorParams Parametro;
    string strAnt=string(mensaje), strPost, strAux;
    size_t pos;
    char *mieq;

    mieq = new char [miequipo.size()+1];
    strcpy(mieq,miequipo.c_str());

    pos = strAnt.find("layer ");   
    cout<<"MENSAJE: "<<strAnt;
    if(pos==-1){
        jugMasCerca.Distancia=0;
    }
    
    while(pos!=-1){

        //en cada ejecucion nos aseguramos de tener las variables auxiliares vacias.
        strAux.erase();
        strPost.erase();

        strPost = strAnt.substr(pos+6);  //ahora tenemos una cadena con lo que sigue desde layer+6 hasta el final
        pos = strPost.find("((");    //lo siguiente a buscar es el inicio del siguiente parametro en la cadena

        if(pos!=-1){		        //si encuentra la continuacion con otro parametro x corta desde el inicio hasta el
            strAux = strPost.substr(0,pos); // en strAux existira una cadena del tipo "Grupo1 2) 20.1 -44 -0 0.1)"
            strAnt = strPost.substr(pos);  // en strAnt existira el resto de la cadena una vez extraida la subcadena buscada
        }else{						
            strAux = strPost;		
            strAnt = strPost;
        }
        pos = strAnt.find("layer ");  // se vuelve a buscar por si existen más jugadores y continua con el bucle
       
        //ahora se trata la strAux si es que tiene algo.

        if(strAux.size()>12){
          char *aux;
          char * pch; //tokens de la subcadena
          int cont = 1;

          aux = new char [strAux.size()+1];
          strcpy(aux,strAux.c_str());

          pch = strtok(aux," (()");

          while (pch != NULL)
          {
            if(cont == 1){		//equipo
                if (strcmp(mieq,pch)!=0){
                    break;
                }
                else{
                    Parametro.Equipo=pch;
                }
            }
            else if(cont == 2){ //dorsal
                Parametro.Dorsal=atoi(pch);
            }
            else if(cont == 3){ //distancia
                Parametro.Distancia=atof(pch);
            }
            else if(cont == 4){ //angulo
                Parametro.Angulo=atof(pch);
            }
            else if(cont == 5){ //velocidad [0]
                Parametro.Velocidad[0]=atof(pch);
            }
            else if(cont == 6){ //velocidad [1]
                Parametro.Velocidad[1]=atof(pch);
            }
            cont++;
            pch = strtok (NULL, " (()");
          }

          if(Parametro.Distancia<jugMasCerca.Distancia){
              jugMasCerca = Parametro;
          }
        }
    }

    return jugMasCerca;
}
void Parsing::iniciar(string &mensaje, int *numero, char *lado)
{

    size_t i= mensaje.find("l");
    if (i!=string::npos)
    {
        *lado='l';
        *numero=atoi(mensaje.substr(i+1).c_str());
    }
    else
    {
        *lado='r';
        *numero=atoi(mensaje.substr(mensaje.find("r")+1).c_str());
    }

}

int Parsing::fisico(string &mensaje, float *velocidad)
{
    size_t i= mensaje.find("speed");
    if (i!=string::npos)
    {
        i=mensaje.find(" ",i);
        *velocidad=atof(mensaje.substr(i).c_str());
    }
    i= mensaje.find(" ");
    int ciclo;
    if (i!=string::npos)
    {
        i=mensaje.find(" ",i);
        ciclo=atoi(mensaje.substr(i).c_str());
    }
return ciclo;


}

int Parsing::ciclo(string &mensaje)
{
    int i= mensaje.find(" ");
    int ciclo;
    if (i!=string::npos)
    {
        i=mensaje.find(" ",i);
        ciclo=atoi(mensaje.substr(i).c_str());
    }
    return ciclo;
}
